home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / gauntlet.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  14KB  |  530 lines

  1. /***************************************************************************
  2.  
  3.     Atari Gauntlet hardware
  4.  
  5. ****************************************************************************/
  6.  
  7.  
  8. #include "driver.h"
  9. #include "machine/atarigen.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. #define XCHARS 42
  13. #define YCHARS 30
  14.  
  15. #define XDIM (XCHARS*8)
  16. #define YDIM (YCHARS*8)
  17.  
  18.  
  19.  
  20. /*************************************
  21.  *
  22.  *    Globals we own
  23.  *
  24.  *************************************/
  25.  
  26. UINT8 vindctr2_screen_refresh;
  27.  
  28.  
  29.  
  30. /*************************************
  31.  *
  32.  *    Statics
  33.  *
  34.  *************************************/
  35.  
  36. struct mo_data
  37. {
  38.     struct osd_bitmap *bitmap;
  39.     UINT8 color_xor;
  40. };
  41.  
  42. static struct atarigen_pf_state pf_state;
  43.  
  44. static UINT8 playfield_color_base;
  45.  
  46.  
  47.  
  48. /*************************************
  49.  *
  50.  *    Prototypes
  51.  *
  52.  *************************************/
  53.  
  54. static const UINT8 *update_palette(void);
  55.  
  56. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  57. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  58. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param);
  59.  
  60. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  61. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  62.  
  63.  
  64.  
  65. /*************************************
  66.  *
  67.  *    Video system start
  68.  *
  69.  *************************************/
  70.  
  71. int gauntlet_vh_start(void)
  72. {
  73.     static struct atarigen_mo_desc mo_desc =
  74.     {
  75.         1024,                /* maximum number of MO's */
  76.         2,                   /* number of bytes per MO entry */
  77.         0x800,               /* number of bytes between MO words */
  78.         3,                   /* ignore an entry if this word == 0xffff */
  79.         3, 0, 0x3ff,         /* link = (data[linkword] >> linkshift) & linkmask */
  80.         0                    /* render in reverse link order */
  81.     };
  82.  
  83.     static struct atarigen_pf_desc pf_desc =
  84.     {
  85.         8, 8,                /* width/height of each tile */
  86.         64, 64                /* number of tiles in each direction */
  87.     };
  88.  
  89.     /* reset statics */
  90.     memset(&pf_state, 0, sizeof(pf_state));
  91.     playfield_color_base = vindctr2_screen_refresh ? 0x10 : 0x18;
  92.  
  93.     /* initialize the playfield */
  94.     if (atarigen_pf_init(&pf_desc))
  95.         return 1;
  96.  
  97.     /* initialize the motion objects */
  98.     if (atarigen_mo_init(&mo_desc))
  99.     {
  100.         atarigen_pf_free();
  101.         return 1;
  102.     }
  103.  
  104.     return 0;
  105. }
  106.  
  107.  
  108.  
  109. /*************************************
  110.  *
  111.  *    Video system shutdown
  112.  *
  113.  *************************************/
  114.  
  115. void gauntlet_vh_stop(void)
  116. {
  117.     atarigen_pf_free();
  118.     atarigen_mo_free();
  119. }
  120.  
  121.  
  122.  
  123. /*************************************
  124.  *
  125.  *    Horizontal scroll register
  126.  *
  127.  *************************************/
  128.  
  129. WRITE_HANDLER( gauntlet_hscroll_w )
  130. {
  131.     /* update memory */
  132.     int oldword = READ_WORD(&atarigen_hscroll[offset]);
  133.     int newword = COMBINE_WORD(oldword, data);
  134.     WRITE_WORD(&atarigen_hscroll[offset], newword);
  135.  
  136.     /* update parameters */
  137.     pf_state.hscroll = newword & 0x1ff;
  138.     atarigen_pf_update(&pf_state, cpu_getscanline());
  139. }
  140.  
  141.  
  142.  
  143. /*************************************
  144.  *
  145.  *    Vertical scroll/PF bank register
  146.  *
  147.  *************************************/
  148.  
  149. WRITE_HANDLER( gauntlet_vscroll_w )
  150. {
  151.     /* update memory */
  152.     int oldword = READ_WORD(&atarigen_vscroll[offset]);
  153.     int newword = COMBINE_WORD(oldword, data);
  154.     WRITE_WORD(&atarigen_vscroll[offset], newword);
  155.  
  156.     /* update parameters */
  157.     pf_state.vscroll = (newword >> 7) & 0x1ff;
  158.     pf_state.param[0] = newword & 3;
  159.     atarigen_pf_update(&pf_state, cpu_getscanline());
  160. }
  161.  
  162.  
  163.  
  164. /*************************************
  165.  *
  166.  *    Playfield RAM write handler
  167.  *
  168.  *************************************/
  169.  
  170. WRITE_HANDLER( gauntlet_playfieldram_w )
  171. {
  172.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  173.     int newword = COMBINE_WORD(oldword, data);
  174.     if (oldword != newword)
  175.     {
  176.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  177.         atarigen_pf_dirty[offset / 2] = 0xff;
  178.     }
  179. }
  180.  
  181.  
  182.  
  183. /*************************************
  184.  *
  185.  *    Periodic scanline updater
  186.  *
  187.  *************************************/
  188.  
  189. void gauntlet_scanline_update(int scanline)
  190. {
  191.     atarigen_mo_update_slip_512(atarigen_spriteram, pf_state.vscroll, scanline, &atarigen_alpharam[0xf80]);
  192. }
  193.  
  194.  
  195.  
  196. /*************************************
  197.  *
  198.  *    Main refresh
  199.  *
  200.  *************************************/
  201.  
  202. void gauntlet_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  203. {
  204.     /* update the palette, and mark things dirty */
  205.     if (update_palette())
  206.         memset(atarigen_pf_dirty, 0xff, atarigen_playfieldram_size / 2);
  207.  
  208.     /* draw the playfield */
  209.     memset(atarigen_pf_visit, 0, 64*64);
  210.     atarigen_pf_process(pf_render_callback, bitmap, &Machine->drv->visible_area);
  211.  
  212.     /* draw the motion objects */
  213.     atarigen_mo_process(mo_render_callback, bitmap);
  214.  
  215.     /* draw the alphanumerics */
  216.     {
  217.         const struct GfxElement *gfx = Machine->gfx[1];
  218.         int x, y, offs;
  219.  
  220.         for (y = 0; y < YCHARS; y++)
  221.             for (x = 0, offs = y * 64; x < XCHARS; x++, offs++)
  222.             {
  223.                 int data = READ_WORD(&atarigen_alpharam[offs * 2]);
  224.                 int code = data & 0x3ff;
  225.                 int opaque = data & 0x8000;
  226.  
  227.                 if (code || opaque)
  228.                 {
  229.                     int color = ((data >> 10) & 0xf) | ((data >> 9) & 0x20);
  230.                     drawgfx(bitmap, gfx, code, color, 0, 0, 8 * x, 8 * y, 0, opaque ? TRANSPARENCY_NONE : TRANSPARENCY_PEN, 0);
  231.                 }
  232.             }
  233.     }
  234.  
  235.     /* update onscreen messages */
  236.     atarigen_update_messages();
  237. }
  238.  
  239.  
  240.  
  241. /*************************************
  242.  *
  243.  *    Palette management
  244.  *
  245.  *************************************/
  246.  
  247. static const UINT8 *update_palette(void)
  248. {
  249.     UINT16 pf_map[32], al_map[64], mo_map[16];
  250.     int i, j;
  251.  
  252.     /* reset color tracking */
  253.     memset(mo_map, 0, sizeof(mo_map));
  254.     memset(pf_map, 0, sizeof(pf_map));
  255.     memset(al_map, 0, sizeof(al_map));
  256.     palette_init_used_colors();
  257.  
  258.     /* update color usage for the playfield */
  259.     atarigen_pf_process(pf_color_callback, pf_map, &Machine->drv->visible_area);
  260.  
  261.     /* update color usage for the mo's */
  262.     atarigen_mo_process(mo_color_callback, mo_map);
  263.  
  264.     /* update color usage for the alphanumerics */
  265.     {
  266.         const unsigned int *usage = Machine->gfx[1]->pen_usage;
  267.         int x, y, offs;
  268.  
  269.         for (y = 0; y < YCHARS; y++)
  270.             for (x = 0, offs = y * 64; x < XCHARS; x++, offs++)
  271.             {
  272.                 int data = READ_WORD(&atarigen_alpharam[offs * 2]);
  273.                 int code = data & 0x3ff;
  274.                 int color = ((data >> 10) & 0xf) | ((data >> 9) & 0x20);
  275.                 al_map[color] |= usage[code];
  276.             }
  277.     }
  278.  
  279.     /* rebuild the playfield palette */
  280.     for (i = 0; i < 16; i++)
  281.     {
  282.         UINT16 used = pf_map[i + 16];
  283.         if (used)
  284.             for (j = 0; j < 16; j++)
  285.                 if (used & (1 << j))
  286.                     palette_used_colors[0x200 + i * 16 + j] = PALETTE_COLOR_USED;
  287.     }
  288.  
  289.     /* rebuild the motion object palette */
  290.     for (i = 0; i < 16; i++)
  291.     {
  292.         UINT16 used = mo_map[i];
  293.         if (used)
  294.         {
  295.             palette_used_colors[0x100 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  296.             palette_used_colors[0x100 + i * 16 + 1] = PALETTE_COLOR_TRANSPARENT;
  297.             for (j = 2; j < 16; j++)
  298.                 if (used & (1 << j))
  299.                     palette_used_colors[0x100 + i * 16 + j] = PALETTE_COLOR_USED;
  300.         }
  301.     }
  302.  
  303.     /* rebuild the alphanumerics palette */
  304.     for (i = 0; i < 64; i++)
  305.     {
  306.         UINT16 used = al_map[i];
  307.         if (used)
  308.             for (j = 0; j < 4; j++)
  309.                 if (used & (1 << j))
  310.                     palette_used_colors[0x000 + i * 4 + j] = PALETTE_COLOR_USED;
  311.     }
  312.  
  313.     /* recalc */
  314.     return palette_recalc();
  315. }
  316.  
  317.  
  318.  
  319. /*************************************
  320.  *
  321.  *    Playfield palette
  322.  *
  323.  *************************************/
  324.  
  325. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  326. {
  327.     const unsigned int *usage = &Machine->gfx[0]->pen_usage[state->param[0] * 0x1000];
  328.     UINT16 *colormap = (UINT16 *)param;
  329.     int x, y;
  330.  
  331.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  332.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  333.         {
  334.             int offs = x * 64 + y;
  335.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  336.             int code = (data & 0xfff) ^ 0x800;
  337.             int color = playfield_color_base + ((data >> 12) & 7);
  338.             colormap[color] |= usage[code];
  339.             colormap[color ^ 8] |= usage[code];
  340.  
  341.             /* also mark unvisited tiles dirty */
  342.             if (!atarigen_pf_visit[offs]) atarigen_pf_dirty[offs] = 0xff;
  343.         }
  344. }
  345.  
  346.  
  347.  
  348. /*************************************
  349.  *
  350.  *    Playfield rendering
  351.  *
  352.  *************************************/
  353.  
  354. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  355. {
  356.     const struct GfxElement *gfx = Machine->gfx[0];
  357.     struct osd_bitmap *bitmap = param;
  358.     int bank = state->param[0];
  359.     int x, y;
  360.  
  361.     /* first update any tiles whose color is out of date */
  362.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  363.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  364.         {
  365.             int offs = x * 64 + y;
  366.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  367.  
  368.             if (atarigen_pf_dirty[offs] != bank)
  369.             {
  370.                 int color = playfield_color_base + ((data >> 12) & 7);
  371.                 int code = bank * 0x1000 + ((data & 0xfff) ^ 0x800);
  372.                 int hflip = data & 0x8000;
  373.  
  374.                 drawgfx(atarigen_pf_bitmap, gfx, code, color, hflip, 0, 8 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  375.                 atarigen_pf_dirty[offs] = bank;
  376.             }
  377.  
  378.             /* track the tiles we've visited */
  379.             atarigen_pf_visit[offs] = 1;
  380.         }
  381.  
  382.     /* then blast the result */
  383.     x = -state->hscroll;
  384.     y = -state->vscroll;
  385.     copyscrollbitmap(bitmap, atarigen_pf_bitmap, 1, &x, 1, &y, clip, TRANSPARENCY_NONE, 0);
  386. }
  387.  
  388.  
  389.  
  390. /*************************************
  391.  *
  392.  *    Playfield overrendering
  393.  *
  394.  *************************************/
  395.  
  396. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  397. {
  398.     const struct GfxElement *gfx = Machine->gfx[0];
  399.     const struct mo_data *modata = param;
  400.     struct osd_bitmap *bitmap = modata->bitmap;
  401.     int color_xor = modata->color_xor;
  402.     int bank = state->param[0];
  403.     int x, y;
  404.  
  405.     /* first update any tiles whose color is out of date */
  406.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  407.     {
  408.         int sy = (8 * y - state->vscroll) & 0x1ff;
  409.         if (sy >= YDIM) sy -= 0x200;
  410.  
  411.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  412.         {
  413.             int offs = x * 64 + y;
  414.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  415.             int color = playfield_color_base + ((data >> 12) & 7);
  416.             int code = bank * 0x1000 + ((data & 0xfff) ^ 0x800);
  417.             int hflip = data & 0x8000;
  418.             int sx = (8 * x - state->hscroll) & 0x1ff;
  419.             if (sx >= XDIM) sx -= 0x200;
  420.  
  421.             drawgfx(bitmap, gfx, code, color ^ color_xor, hflip, 0, sx, sy, 0, TRANSPARENCY_THROUGH, palette_transparent_pen);
  422.         }
  423.     }
  424. }
  425.  
  426.  
  427.  
  428. /*************************************
  429.  *
  430.  *    Motion object palette
  431.  *
  432.  *************************************/
  433.  
  434. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  435. {
  436.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  437.     UINT16 *colormap = param;
  438.     int code = (data[0] & 0x7fff) ^ 0x800;
  439.     int hsize = ((data[2] >> 3) & 7) + 1;
  440.     int vsize = (data[2] & 7) + 1;
  441.     int color = data[1] & 0x000f;
  442.     int tiles = hsize * vsize;
  443.     UINT16 temp = 0;
  444.     int i;
  445.  
  446.     for (i = 0; i < tiles; i++)
  447.         temp |= usage[code++];
  448.     colormap[color] |= temp;
  449. }
  450.  
  451.  
  452.  
  453. /*************************************
  454.  *
  455.  *    Motion object rendering
  456.  *
  457.  *************************************/
  458.  
  459. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  460. {
  461.     const struct GfxElement *gfx = Machine->gfx[0];
  462.     const unsigned int *usage = gfx->pen_usage;
  463.     unsigned int total_usage = 0;
  464.     struct osd_bitmap *bitmap = param;
  465.     struct rectangle pf_clip;
  466.     int x, y, sx, sy;
  467.  
  468.     /* extract data from the various words */
  469.     int code = (data[0] & 0x7fff) ^ 0x800;
  470.     int color = data[1] & 0x000f;
  471.     int ypos = -pf_state.vscroll - (data[2] >> 7);
  472.     int hflip = data[2] & 0x0040;
  473.     int hsize = ((data[2] >> 3) & 7) + 1;
  474.     int vsize = (data[2] & 7) + 1;
  475.     int xpos = -pf_state.hscroll + (data[1] >> 7);
  476.     int xadv;
  477.  
  478.     /* adjust for height */
  479.     ypos -= vsize * 8;
  480.  
  481.     /* adjust the final coordinates */
  482.     xpos &= 0x1ff;
  483.     ypos &= 0x1ff;
  484.     if (xpos >= XDIM) xpos -= 0x200;
  485.     if (ypos >= YDIM) ypos -= 0x200;
  486.  
  487.     /* determine the bounding box */
  488.     atarigen_mo_compute_clip_8x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  489.  
  490.     /* adjust for h flip */
  491.     if (hflip)
  492.         xpos += (hsize - 1) * 8, xadv = -8;
  493.     else
  494.         xadv = 8;
  495.  
  496.     /* loop over the height */
  497.     for (y = 0, sy = ypos; y < vsize; y++, sy += 8)
  498.     {
  499.         /* clip the Y coordinate */
  500.         if (sy <= clip->min_y - 8)
  501.         {
  502.             code += hsize;
  503.             continue;
  504.         }
  505.         else if (sy > clip->max_y)
  506.             break;
  507.  
  508.         /* loop over the width */
  509.         for (x = 0, sx = xpos; x < hsize; x++, sx += xadv, code++)
  510.         {
  511.             /* clip the X coordinate */
  512.             if (sx <= -8 || sx >= XDIM)
  513.                 continue;
  514.  
  515.             /* draw the sprite */
  516.             drawgfx(bitmap, gfx, code, color, hflip, 0, sx, sy, clip, TRANSPARENCY_PEN, 0);
  517.             total_usage |= usage[code];
  518.         }
  519.     }
  520.  
  521.     /* overrender the playfield */
  522.     if (total_usage & 0x0002)
  523.     {
  524.         struct mo_data modata;
  525.         modata.bitmap = bitmap;
  526.         modata.color_xor = (color == 0 && vindctr2_screen_refresh) ? 0 : 8;
  527.         atarigen_pf_process(pf_overrender_callback, &modata, &pf_clip);
  528.     }
  529. }
  530.